// MIT License
// 开源地址：https://gitee.com/co1024/AbcMvc
// Copyright (c) 2021-2023 1024
// Abc.Mvc=Furion+EF+SqlSugar+Pear layui admin.

using Furion.DynamicApiController;

namespace Abc.Application.HtAdminServices;

/// <summary>
/// 菜单表
/// </summary>
[ApiDescriptionSettings("HtAdmin", Name = "HtMenu")]
[MaApi(area: "API", controller: "HtMenu", controllerDescription: "菜单管理", PCode = "API")]
[IgnoreAntiforgeryToken]
public class HtMenuService : IHtMenuService, ITransient, IDynamicApiController
{
    private readonly ILogger<HtMenuService> _logger;
    private readonly IRepository<SysMenu> _repository;

    public HtMenuService(ILogger<HtMenuService> logger
  , IRepository<SysMenu> repository)
    {
        _logger = logger;
        _repository = repository;
    }

    /// <summary>
    /// 新增或更新一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [MaPermission(name: "新增或更新一条", actions: "InsertOrUpdate")]
    public async Task InsertOrUpdate(HtMenuInput input)
    {
        if (input.Id > 0)
        {
            var dbentity = await _repository.FirstOrDefaultAsync(r => r.Id == input.Id);
            input.Adapt(dbentity);
            dbentity.IsAutoGeneration = false;//修改后，设置为不是自动生成，防止下次生成覆盖
            dbentity.Icon = $"layui-icon {dbentity.Icon}";
        }
        else
        {
            var add = input.Adapt<SysMenu>();
            add.Icon = $"layui-icon {add.Icon}";
            var newEntity = await _repository.InsertAsync(add);
        }
    }

    /// <summary>
    /// 删除一条
    /// </summary>
    /// <param name="id"></param>
    [MaPermission(name: "删除一条", actions: "Delete")]
    public async Task Delete(long id)
    {
        var dbmenu = await _repository.FirstAsync(o => o.Id == id);
        if (dbmenu.IsSystem == false)
        {
            await _repository.Where(o => o.Id == id).ExecuteDeleteAsync();
        }
        else
        {
            Oops.Bah("系统菜单不能删除");
        }
    }

    /// <summary>
    /// 批量假删除
    /// </summary>
    /// <param name="ids">需要删除的数据，多条以英文逗号隔开</param>
    [MaPermission(name: "批量假删除", actions: "BatchFakeDelete")]
    public async Task BatchFakeDelete(string ids)
    {
        var idtemps = ids.ToIntList();
        await _repository.Where(r => idtemps.Any(a => a == r.Id))
            .ExecuteUpdateAsync(u =>
                u.SetProperty(f => f.IsDeleted, n => true)
            );
    }

    /// <summary>
    /// 查询一条[跟踪实体]
    /// </summary>
    /// <param name="id"></param>
    [MaPermission(name: "查询一条", actions: "Get")]
    public async Task<HtMenuOut> Get(long id)
    {
        var dbentity = await _repository.DetachedEntities.FirstOrDefaultAsync(o => o.Id == id);
        if (dbentity == null) return null;
        return dbentity.Adapt<HtMenuOut>();
    }

    /// <summary>
    /// 查询一条[跟踪实体]
    /// </summary>
    /// <param name="code"></param>
    [MaPermission(name: "查询一条", actions: "GetByCode")]
    public async Task<HtMenuOut> GetByCode(string code)
    {
        SysMenu entity = await _repository.DetachedEntities.FirstOrDefaultAsync(o => o.Code == code);
        return entity?.Adapt<HtMenuOut>();
    }

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="searchQuery"></param>
    /// <returns></returns>
    [MaPermission(name: "分页查询", actions: "GetAllByPage")]
    public async Task<LayuiPagedList<HtMenuOut>> GetAllByPageToLayui(HtMenuQuery searchQuery)
    {
        var queryable = _repository.DetachedEntities.AsQueryable();

        if (!string.IsNullOrWhiteSpace(searchQuery.AreaName))
        {
            var kw = searchQuery.AreaName.ToLower();
            queryable = queryable.Where(o => o.Area != null && o.Area.ToLower() == kw);
        }

        if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
        {
            var kw = searchQuery.KeyWords.ToLower();
            queryable = queryable.Where(o => o.Name.Contains(kw)
|| (o.Code != null && o.Code.ToLower().Contains(kw))
|| (o.Url != null && o.Url.ToLower().Contains(kw)));
        }

        var resultpage = queryable.OrderByDescending(o => o.Id).ProjectToType<HtMenuOut>();
        //foreach (var item in resultpage.data)
        //{
        //    // item.PermissionStr = entities.First(o => o.Id == item.Id).Permissions?.Select(o => o.Name)?.StringJoin(",") ?? "";
        //}

        return await resultpage.ToLayuiPagedListAsync(searchQuery.Page, searchQuery.Limit);
    }

    /// <summary>
    /// 设置状态
    /// </summary>
    /// <param name="id"></param>
    /// <param name="state"></param>
    /// <param name="field">字段名</param>
    /// <returns></returns>
    [MaPermission(name: "设置状态", actions: "SetState")]
    public async Task SetState(long id, bool state, string field)
    {
        var entity = await _repository.FirstAsync(o => o.Id == id);
        switch (field.ToLower())
        {
            case "isenable": entity.IsEnable = state; break;
            case "isexpand": entity.IsExpand = state; break;
            case "isdisuse": entity.IsDisuse = state; break;
            case "issystem": entity.IsSystem = state; break;
            case "isshow": entity.IsShow = state; break;
            case "isautogeneration": entity.IsAutoGeneration = state; break;
            case "isdeleted": entity.IsDeleted = state; break;
            default: break;
        }
    }

    /// <summary>
    /// 获取MenuPermission Area 集合
    /// </summary>
    /// <returns></returns>
    [MaPermission(name: "获取MenuPermission Area 集合", actions: "GetMenuAreas")]
    public async Task<List<string>> GetMenuAreas()
    {
        List<string> areas = await _repository.DetachedEntities.Select(o => o.Area).Distinct().ToListAsync();
        return areas;
    }

    /// <summary>
    /// 查询菜单下拉树
    /// </summary>
    /// <returns></returns>
    [MaPermission(name: "查询菜单下拉树", actions: "GetDtree")]
    public async Task<Dtree> GetDtree(string pid = "")
    {
        var dtreeEntities = await _repository.DetachedEntities
            .Select(o => new DtreeEntity { id = o.Code, pid = o.PCode, name = o.Name, sort = o.Sort })
            .ToListAsync();
        var dtree = dtreeEntities.GetDtree(pid);
        return dtree;
    }

    /// <summary>
    /// 获取后台左侧菜单列表
    /// </summary>
    /// <param name="area">区域</param>
    /// <returns></returns>
    [MaPermission(name: "获取后台左侧菜单列表", actions: "GetMenus")]
    public async Task<List<PearMenuItemOut>> GetMenus(string area)
    {
        var dbmenus = await _repository.DetachedEntities
           .Where(o => o.IsEnable && o.IsShow)
           .Select(o => new PearMenuItem() { MenuType = o.MenuType, Code = o.Code, PCode = o.PCode, Name = o.Name, Icon = o.Icon, Sort = o.Sort, Url = o.Url }).ToListAsync();
        var rmenus = dbmenus.GetMenus(pid: area);
        return rmenus;
    }
}